package com.baizhi.cmfz.config;

import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

@Configuration
public class ShiroConfig {
    /**
     * 配置过滤器工厂
     * 拦截（过滤）规则
     * @return
     */
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager securityManager){

        ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
        /**
         * 配置拦截规则  setFilterChainDefinitionMap 设置过滤器链
         * anon 代表匿名可访问
         * authc 代表认证可访问
         */
        Map map = new HashMap();
        map.put("/login.jsp","anon");
        map.put("/login/*","anon");

        map.put("/main.jsp", "authc");
        map.put("/guru/*", "authc");
        map.put("/menu/*", "authc");
        map.put("/jsp/*", "authc");

        factoryBean.setFilterChainDefinitionMap(map);
        /**
         * 配置安全管理器
         */
        factoryBean.setSecurityManager(securityManager);

        return factoryBean;
    }

    @Bean
    public DefaultWebSecurityManager securityManager(AuthorRealm authenRealm){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        //需要自定义Realm
        securityManager.setRealm(authenRealm);
        return  securityManager;
    }

    @Bean
    public AuthorRealm authenRealm(HashedCredentialsMatcher hashedCredentialsMatcher){
        AuthorRealm authorRealm = new AuthorRealm();
//        设置加密规则  默认不加密 修改默认为MD5加密
        authorRealm.setCredentialsMatcher(hashedCredentialsMatcher);
        return authorRealm;
    }

    /**
     * 密码校验规则HashedCredentialsMatcher
     */
    @Bean
    public HashedCredentialsMatcher hashedCredentialsMatcher() {
        HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
        //指定加密方式为MD5 SHA
        credentialsMatcher.setHashAlgorithmName("MD5");
        //加密次数 散列次数   必须和注册时候散列次数保持一致
        credentialsMatcher.setHashIterations(1024);
        credentialsMatcher.setStoredCredentialsHexEncoded(true);
        return credentialsMatcher;
    }





    /**
     *  开启shiro aop注解支持
     *  使用代理方式;所以需要开启代码支持;否则@RequiresRoles等注解无法生效
     * @param securityManager
     * @return
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager){
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }






    //自定义数据源->安全管理器->factory

    /**      配置文件数据源认证步骤
     *      读取ini配置文件获取工厂factory->用工厂生成安全管理器securityManager->将安全管理器作为参数赋值给utils->
     *      utils获取subject主体->调用方法login 参数是token令牌 令牌包含用户名和密码
     */

    /**
     *      自定义数据源之后的认证步骤
     *      utils获取subject主体->调用方法login 参数是token令牌 令牌包含用户名和密码
     */
}
